package com.example.rouroudate.ui.home

import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.example.rouroudate.R
import com.example.rouroudate.databinding.FragmentHomeBinding
import com.example.rouroudate.ui.gallery.ui.StyleAnimationView
import com.example.rouroudate.ui.home.ui.CircleDate
import com.example.rouroudate.ui.home.ui.DateView
import com.example.rouroudate.ui.widget.CurrentDateSetDialog
import com.example.rouroudate.ui.widget.DataEventBus
import com.example.rouroudate.ui.widget.ViewPagerTransformer
import com.example.rouroudate.util.CompatUtils.getTabIcon
import com.example.rouroudate.util.DisplayUtils
import com.example.rouroudate.util.PrefManager
import com.example.rouroudate.util.TimeUtils
import com.example.rouroudate.util.TimeUtils.isGreatThanToday
import com.example.rouroudate.util.ToastUtils
import com.google.android.material.tabs.TabLayout
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.util.*

class HomeFragment : Fragment() {

    companion object {
        const val TAG = "HomeFragment"
    }

    private var midPageIndex = 0

    private var _binding: FragmentHomeBinding? = null

    private val binding get() = _binding!!

    private lateinit var viewPager: ViewPager

    private var dateSettingData = PrefManager.getDateSetting()

    private val views = LinkedList<DateView>()

    private val viewData = ArrayList<CircleDate>()

    private var currentStyleType = PrefManager.getStyleType()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentHomeBinding.inflate(inflater, container, false)
        initView()
        return binding.root
    }

    private fun initView() {
        initViewPageData()
        binding.setting.apply {
            val h =
                DisplayUtils.getScreenHeight() - DisplayUtils.dp2px(150f) - DisplayUtils.getScreenWidth()
            val layoutParams = this.layoutParams
            layoutParams.height = h
        }
        binding.setDate.setOnClickListener(::handlerSetDate)
        viewPager = binding.viewPager.apply {
            adapter = viewPagerAdapter
            currentItem = midPageIndex
        }
        binding.tabLayout.apply {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                tooltipText = ""
            }
            setupWithViewPager(viewPager)
            repeat(tabCount) { idx ->
                val tab = getTabAt(idx)!!
                tab.icon = getTabIcon(currentStyleType)
            }
        }
        initDataEvent()
    }

    private fun initDataEvent() {
        lifecycleScope.launch {
            DataEventBus.dateSettingData.collect {
                Log.d(TAG, "dateSettingData")
                dateSettingData = it
                initViewPageData()
                viewPager.let { vp ->
                    vp.adapter = viewPagerAdapter
                    vp.currentItem = midPageIndex
                }
            }
        }
        lifecycleScope.launch {
            DataEventBus.styleSettingType.collect {
                Log.d(TAG, "styleSettingType")
                currentStyleType = it
                viewPager.adapter = viewPagerAdapter
                initTabLayout()
            }
        }

        lifecycleScope.launch {
            DataEventBus.deleteStartDate.collect {
                Log.d(TAG, "deleteStartDate")
                initViewPageData()
                viewPager.let { vp ->
                    vp.adapter = viewPagerAdapter
                    vp.currentItem = midPageIndex
                }
                initTabLayout()
            }
        }
    }

    private fun initViewPageData() {
        viewData.apply {
            clear()
            val dateList = PrefManager.getStartDateArray(PrefManager.SortTypeUp)
            val currentDate = if (dateList.size == 0) {
                val t = CircleDate()
                t.settingData = dateSettingData.copy()
                add(t.deepCopy())
                t
            } else {
                val t = dateList[dateList.size - 1].deepCopy()
                addAll(dateList.subList(0, dateList.size - 1))
                if (t.isCurrentDate()) {
                    dateList[dateList.size - 1].settingData = dateSettingData.copy()
                    PrefManager.setStartDate(dateList[dateList.size - 1])
                    add(dateList[dateList.size - 1])
                    t.settingData = dateSettingData.copy()
                    t
                } else {
                    add(dateList[dateList.size - 1])
                    t.addDay(t.settingData.dateSize)
                    val size = TimeUtils.getDateSize(CircleDate(), t) + 1
                    if (size < dateSettingData.dateSize) {
                        t.settingData.dateSize = dateSettingData.dateSize
                    } else {
                        t.settingData.dateSize = size
                    }
                    add(t)
                    t
                }
            }
            val date = currentDate.deepCopy()
            date.settingData = dateSettingData.copy()
            for (i in 0 until 120) {
                date.addDay(dateSettingData.dateSize)
                add(date.deepCopy())
            }
            for (i in 0 until size) {
                if (this[i].isCurrentDate()) {
                    midPageIndex = i
                    break
                }
            }
        }
    }

    private fun handlerSetDate(view: View) {
        Log.d(TAG, "id = ${view.id}")
        val dialog = activity?.let { it1 ->
            CurrentDateSetDialog(it1).apply {
                selectedDay = CircleDate(settingData = dateSettingData.copy())
                setTitle(getString(R.string.set_start_date))
                setCallBack {
                    if (isGreatThanToday(it)) {
                        ToastUtils.show(getString(R.string.date_set_more_than_today))
                        return@setCallBack
                    }
                    ToastUtils.show(when (PrefManager.setStartDate(it)) {
                        PrefManager.SUCCESS -> {
                            initViewPageData()
                            viewPager.let { vp ->
                                vp.adapter = viewPagerAdapter
                                vp.currentItem = midPageIndex
                            }
                            initTabLayout()
                            getString(R.string.edit_success)
                        }
                        PrefManager.FAIL -> {
                            getString(R.string.edit_fail)
                        }
                        else -> {
                            ""
                        }
                    })
                }
            }
        }
        dialog?.show()
    }

    private fun initTabLayout() {
        binding.tabLayout.apply {
            repeat(tabCount) { idx ->
                val tab = getTabAt(idx)!!
                tab.icon = ContextCompat.getDrawable(
                    context, when (currentStyleType) {
                        StyleAnimationView.HeartType -> R.drawable.ic_style_setting_heart
                        StyleAnimationView.CircleType -> R.drawable.ic_style_setting_circle
                        else -> R.drawable.ic_style_setting_polygon
                    }
                )
            }
        }
    }

    private val viewPagerAdapter = object : PagerAdapter() {

        override fun getCount() = viewData.size

        override fun isViewFromObject(view: View, `object`: Any): Boolean {
            return view == `object`
        }

        override fun instantiateItem(container: ViewGroup, position: Int): Any {
            Log.d(TAG, "instantiateItem")
            val view = if (views.size > 0) {
                views.removeFirst()
            } else {
                DateView(requireContext())
            }
            view.setDateView(viewData[position])
            view.setBackToday { viewPager.setCurrentItem(midPageIndex, true) }
            if (view.parent == null) {
                container.addView(view)
            }
            return view
        }

        override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
            val view = `object` as DateView
            container.removeView(view)
            views.add(view)
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}